/*!
 * \file frcomm.h
 *
 * \brief 共通定义
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 * 共通定义
 *
 * \version 2.0
 * \author yaohl
 * \date 2014/10/09
 *
 */
 
#ifndef __FRCOMM_H_
#define __FRCOMM_H_

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define FRAME_DEBUG    0

#if FRAME_DEBUG
    void frdbg_print(const char *p_file, int i_line
                   , const char *p_fun, const char *p_fmt , ...);
    #define frdbg_t(fmt,args...) frdbg_print(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args)

    #define frdbg(...) (printf("[%s(%s:%u)]", __func__,__FILE__,__LINE__),\
                         printf(" "__VA_ARGS__))

#else
    #define frdbg_t(...)
    #define frdbg(...)
#endif

#define FR_CMD_MKDIR            "/bin/mkdir"
#define FR_CMD_CP               "/bin/cp"
#define FR_CMD_RM               "/bin/rm"
#define FR_CMD_MV               "/bin/mv"

#define frwarn(...) (printf("[%s(%s:%u)]", __func__,__FILE__,__LINE__),\
                     printf(" "__VA_ARGS__))

#define FR_SUCC         0
#define FR_FAIL         1
#define FR_YES          1
#define FR_NO           0

#define FR_YESNO2STR(x) ((x==FR_YES)?"YES":"NO")
#define FR_SUCCFAIL2STR(x) ((x==FR_SUCC)?"SUCC":"FAIL")
#define FR_L4PROTO2STR(x) ( ((x&IPPROTO_TCP)&&(x&IPPROTO_UDP))?"any": \
                                (x==IPPROTO_TCP ? "tcp" : \
                                        (x==IPPROTO_UDP?"udp":"unknown")) )

#define FR_L4STR2PROTO(x) (strcasecmp(x, "tcp") ? \
                            (strcasecmp(x, "udp") ? (strcasecmp(x, "any") ? -1 : 0) : IPPROTO_UDP):\
                             IPPROTO_TCP)

#ifdef APMTEST_CUNIT
    #define FR_STATIC
#else
    #define FR_STATIC       static
#endif


#define APM_MAC_SIZE       6  /* mac地址长度 */

/* sql文NULL */
#define APM_DB_SQL_NULL               "null"
/* sql文之间分割符 */
#define APM_DB_SQL_SEPARATOR          ";"
/* bind数据之间分割符 */
#define APM_DB_DBBIND_SEPARATOR       ","

#define int_ntoa(x)	inet_ntoa(*((struct in_addr *)&x))

#define FRMAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define FRMAC_ARG(x) ((u_char*)(x))[0],((u_char*)(x))[1],((u_char*)(x))[2],((u_char*)(x))[3],((u_char*)(x))[4],((u_char*)(x))[5]


/*! @brief 2进制数据 */
typedef struct __st_binary_data
{
    char *p_data;
    unsigned int ui_len;
} Frbindata;

/*! @brief 数据类型 */
typedef enum __em_data_type
{
    FRINT = 1,
    FRLONG,
    FRFLOAT,
    FRDOUBLE,
    FRSTRING=6,
    FRTIME,
    FRCLOB,
    FRBLOB,
    FRBOOLEAN,
    FRCHAR,
    FRSHORT,
}Frdata_type;

#define FR_FRDATATYPE2STR(x) (x==FRINT?"FRINT":(x==FRLONG?"FRLONG":(x==FRFLOAT?"FRFLOAT":(x==FRDOUBLE?"FRDOUBLE":(x==FRSTRING?"FRSTRING":(x==FRTIME?"FRTIME":(x==FRCLOB?"FRCLOB":(x==FRBLOB?"FRBLOB":"FRUNKNOWN"))))))))

/*! @brief 字段用Key/Value定义 */
typedef struct __st_data_field
{
    char *p_field_name;       /*!< 字段名 */
    char *p_field_value;      /*!< 字段值 */
    int  i_field_index;       /*!< 字段索引号，从1开始顺序编号 */
    Frdata_type em_data_type; /*!< 字段类型 */
}Frdata_field;

/*! @brief 通用字段 */
typedef struct __st_var_field
{
    char *p_field_name;       /*!< 字段名 */
    Frdata_type em_data_type; /*!< 字段类型 */
    /*!< 根据不同字段类型读取不同值(CLOB和BLOB都用Frbindata) */
    union
    {
        short b_value;              /*!< FRBOOLEAN */
        char c_value;               /*!< FRCHAR */
        short s_value;              /*!< FRSHORT */
        int i_value;                /*!< FRINT */
        long long ll_value;          /*!< FRLONG */
        float f_value;              /*!< FRFLOAT */
        double d_value;             /*!< FRDOUBLE */
        char *p_value;              /*!< FRSTRING */
        long long ll_time_value;    /*!< FRTIME */
        Frbindata *p_st_value;      /*!< FRCLOB FRBLOB */
    }field_value;

    short s_flag_trunc;           /*!< 数据是否截断 FR_NO(0):无;FR_YES(1):有  */
}Frvar_field;

#ifdef FRLINUX4
    #define prctl(a, b)
#endif

#define APM_COREDUMP    {int i_coredump=0; i_coredump=1/0;}

#endif

